﻿// Copyright 2008 Benjamin Jenks 
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may 
// not use this file except in compliance with the License. You may obtain 
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License. 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using iTunesAlbumArtFetcher.Core;
using iTunesAlbumArtFetcher.UI;

namespace iTunesAlbumArtFetcher
{
    public partial class iTunesAlbumArtFetcherForm : Form
    {
        private IEnumerator<iTunes.Track> trackIter;
        private GImageSearch.SearchResults search;
        private ArtworkManager artworkManager= new ArtworkManager();

        public iTunesAlbumArtFetcherForm()
        {
            InitializeComponent();

            // load the first track info
            this.InitialiseAddingArtwork();

            // add handlers to the buttons
            this.nextButton.Click+= (obj, e) => {
                this.artworkManager.Ignore( this.trackIter.Current );
                this.NextTrack();
            };
            this.moreImagesButton.Click+= (obj, e) => {
                this.search = new GImageSearch().NextPage( this.search );
                this.LoadSearchResults( this.trackIter.Current, this.search.Images, false );
            };
            this.searchBox.KeyDown+= (obj, e) => {
                if ( e.KeyCode == Keys.Enter ) { 
                    this.search = new GImageSearch().Query( this.searchBox.Text );
                    this.LoadSearchResults( this.trackIter.Current, this.search.Images, true );
                }
            };
            this.searchBox.GotFocus+= (obj, e) => {
                this.searchBox.BorderStyle= BorderStyle.Fixed3D;
            };

            // draw in some pretty etched lines 
            PaintEventHandler etchedLineDrawerHandler= (obj, e) => {
                Control panel= obj as Control;
                e.Graphics.DrawLine(SystemPens.ControlLight, 0, 0, panel.Width, 0);
                e.Graphics.DrawLine(SystemPens.ControlDarkDark, 0, 1, panel.Width, 1);
            };
            this.artworkPanel.Paint += etchedLineDrawerHandler;
            this.splitter.Paint += etchedLineDrawerHandler;
            this.footerPanel.Paint += etchedLineDrawerHandler;
            this.buttonPanel.Paint += etchedLineDrawerHandler;

            // redraw the etched lines as the form is manipulated
            this.artworkPanel.Resize += (obj, e) => this.artworkPanel.Refresh();
            this.artworkPanel.Scroll += (obj, e) => this.artworkPanel.Refresh();
            this.historyPanel.Scroll += (obj, e) => this.artworkPanel.Refresh();

            // do some funky stuff
            IntPtr hwnd = new System.Windows.Forms.Present
        }

        private void StartAgainOrQuit() {
            DialogResult result= MessageBox.Show( "Would you like to go back to the beginning?", "No More Tracks", MessageBoxButtons.YesNo ); 
            if ( result == DialogResult.Yes ) {
                this.InitialiseAddingArtwork();
                return;
            } else {
                MessageBox.Show( "Thankyou for using the Artwork Fetcher!!" );
                Application.Exit();
            }
        }

        private void InitialiseAddingArtwork() 
        {
            this.trackIter = new iTunes().TracksWithoutArtwork().GetEnumerator();
            this.NextTrack(); 
        }

        private void NextTrack() 
        {
            this.Cursor = Cursors.WaitCursor;
            
            // have we run out of tracks to process?
            if ( !this.trackIter.MoveNext() ) { 
                this.StartAgainOrQuit();
                return;
            }

            iTunes.Track track = this.trackIter.Current;
            this.titleLabel.Text = track.Album + "\n" + track.Artist;

            // do already have artwork for the current album? if so, recurse to the next
            if ( this.artworkManager.TryToAssociateArtwork( track ) || this.artworkManager.IsIgnored( track ) ) { 
                this.NextTrack(); 
                return; 
            }

            this.search= new GImageSearch().Query(track.Album + " " + track.Artist);
            this.LoadSearchResults( track, this.search.Images, true );

            this.Cursor= Cursors.Default;
        }

        private void AddToHistory(iTunes.Track track, GImageSearch.Image image) {
            // just keep a history of the last 8 items
            if ( historyPanel.Controls.Count >= 8 ) { historyPanel.Controls.RemoveAt ( 0 ); }

            HistoryItem item= new HistoryItem { Image= image };
            item.DoubleClick += (o, e) => {
                this.artworkManager.TryToAssociateArtwork( this.trackIter.Current, image );
                this.NextTrack();
            };
            this.historyPanel.Controls.Add( item );
        }

        private void LoadSearchResults(iTunes.Track track, List<GImageSearch.Image> images, bool reset) 
        {
            if ( reset ) { this.artworkPanel.Controls.Clear(); }

            foreach (GImageSearch.Image image in images)
            {
                Thumbnail thumb = new Thumbnail {
                    Image= image
                };
                thumb.DoubleClick += (object o, EventArgs e) => { 
                    try {
                        this.artworkManager.Cache( track, thumb.Image );
                        this.artworkManager.TryToAssociateArtwork( track );
                        this.AddToHistory( track, thumb.Image );
                        this.NextTrack();
                    } catch (Exception ex) {
                        MessageBox.Show( ex.Message, ex.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error );
                        this.artworkPanel.Controls.Remove( thumb );
                        this.artworkPanel.Refresh();
                    }
                };
                this.artworkPanel.Controls.Add( thumb );
            }

            // do we have more results available to load up??
            this.moreImagesButton.Enabled= ( 
                ( this.search.Cursor.CurrentPageIndex + 1 ) < this.search.Cursor.Pages.Count 
            );

            this.artworkPanel.Refresh();
        }
    }
}